package vg.services.graph_view_manager.realization.graph_view.smart_graph_view;

import javax.swing.*;

import vg.interfaces.ll_services.data_base_service.data.graph.Graph;
import vg.services.graph_view_manager.interfaces.graph_view.AGraphView;
import vg.services.graph_view_manager.interfaces.graph_view.IGraphAction;
import vg.services.graph_view_manager.interfaces.tab.ATab;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.SGVGraphRenderer;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.SGVTopScreen;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.SGVPatchManager;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.ExecuteLayoutAction;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.MergeAction;
import vg.services.graph_view_manager.realization.graph_view.smart_graph_view.realization.actions.NewGraphAction;
import vg.services.main_manager.VGMainServiceHelper;
import vg.shared.graph.utils.GraphUtils;

/**
 * This class is wrapper to jgraphx library.
 *
 * @author Timur Zolotuhin (e-mail: tzolotuhin@gmail.com)
 */
public class SmartGraphView extends AGraphView {	
	// Mutex
	private final Object generalMutex = new Object();

	// Main components
	private SGVGraphRenderer sgvGraphViewRenderer;
	private SGVTopScreen sgvTopScreen;
	private SGVPatchManager sgvPatchManager;
	private String title;

    /**
     * Creates graph view from graph.
     */
    public SmartGraphView(Graph graph) {
		super(ATab.DEF_GRAPH_VIEW_TAB_TYPE);
		init();
		
		title = GraphUtils.generateGraphTitle(graph);

		// new graph actions
        addAction(new NewGraphAction(graph));
        addAction(new ExecuteLayoutAction());
	}

    /**
     * Creates graph view from existing graph view and graph, keeping positions, sizes and other
     * fields at the same elements.
     */
    public SmartGraphView(AGraphView srcGraphView, Graph srcGraph) {
		this(srcGraph);

        addAction(new MergeAction(srcGraphView, srcGraph));
	}

    @Override
	public void addAction(IGraphAction patch) {
        sgvPatchManager.addAction(patch);
	}

//=============================================================================
//-----------------IMPLEMENTATION OF AGraphView--------------------------------
    @Override
	public JComponent getView() {
		return sgvTopScreen.getView();
	}
	
	@Override
	public String getTabTitle() {
		synchronized (generalMutex) {
			return title;			
		}
	}
	
	@Override
	public void setTabTitle(String title) {
		synchronized (generalMutex) {
			this.title = title;
		}
	}

//=============================================================================
//-----------------PRIVATE METHODS---------------------------------------------
	private void init() {
		// initialize components
		if (SwingUtilities.isEventDispatchThread()) {
            sgvGraphViewRenderer = new SGVGraphRenderer(this);
		} else {
			try {
				SwingUtilities.invokeAndWait(new Runnable() {
					@Override
					public void run() {
                        sgvGraphViewRenderer = new SGVGraphRenderer(SmartGraphView.this);
					}
				});
			} catch (Exception ex) {
                VGMainServiceHelper.logger.printException(ex);
			}
		}
        sgvTopScreen = new SGVTopScreen(sgvGraphViewRenderer);
        sgvPatchManager = new SGVPatchManager(sgvTopScreen);
	}
}
